//
// Created by QU on 24-9-10.
//

#ifndef INC_09TLV_STICK_TCP_SERVER_H
#define INC_09TLV_STICK_TCP_SERVER_H

#include <boost/asio.hpp>
#include <map>
#include <queue>

#define MAX_LENGTH  1024*2
#define HEAD_LENGTH 2
#define MAX_RECVQUE  10000
#define MAX_SENDQUE 1000

using namespace std;
using boost::asio::ip::tcp;

class CSession;
class MsgNode;

class CServer
{
public:
    CServer(boost::asio::io_context& io_context, short port);
    void ClearSession(std::string);
private:
    void HandleAccept(shared_ptr<CSession>, const boost::system::error_code & error);
    void StartAccept();
    boost::asio::io_context &_io_context;
    short _port;
    tcp::acceptor _acceptor;
    std::map<std::string, shared_ptr<CSession>> _sessions;
};


class MsgNode
{
    friend class CSession;
public:
    MsgNode(char * msg, short max_len):_total_len(max_len + HEAD_LENGTH),_cur_len(0){
        _data = new char[_total_len+1]();
        //转为网络字节序
        int max_len_host = boost::asio::detail::socket_ops::host_to_network_short(max_len);
        // boost::asio::detail::socket_ops::host_to_network_short() 是一个内部函数, 不建议使用,
        // Boost库中的Boost.Endian库提供了便捷的工具来处理字节序转换。
        // 要使用Boost.Endian库，确保你的Boost库版本在1.58.0或更高，因为Boost.Endian是在这个版本中引入的。
        memcpy(_data, &max_len_host, HEAD_LENGTH);
        memcpy(_data+ HEAD_LENGTH, msg, max_len);
        _data[_total_len] = '\0';
    }

    MsgNode(short max_len):_total_len(max_len),_cur_len(0) {
        _data = new char[_total_len +1]();
    }

    ~MsgNode() {
        delete[] _data;
    }

    void Clear() {
        ::memset(_data, 0, _total_len);
        _cur_len = 0;
    }
private:
    short _cur_len;
    short _total_len;
    char* _data;
};

class CSession: public std::enable_shared_from_this<CSession>
{
public:
    CSession(boost::asio::io_context& io_context, CServer* server);
    ~CSession();
    tcp::socket& GetSocket();
    std::string& GetUuid();
    void Start();
    void Send(char* msg,  int max_length);
    void Close();
    std::shared_ptr<CSession> SharedSelf();
private:
    void HandleRead(const boost::system::error_code& error, size_t  bytes_transferred, std::shared_ptr<CSession> shared_self);
    void HandleWrite(const boost::system::error_code& error, std::shared_ptr<CSession> shared_self);
    tcp::socket _socket;
    std::string _uuid;
    char _data[MAX_LENGTH];
    CServer* _server;
    bool _b_close;
    std::queue<shared_ptr<MsgNode> > _send_que;
    std::mutex _send_lock;
    //收到的消息结构
    std::shared_ptr<MsgNode> _recv_msg_node;
    bool _b_head_parse;
    //收到的头部结构
    std::shared_ptr<MsgNode> _recv_head_node;
};


int main();

#endif //INC_09TLV_STICK_TCP_SERVER_H
